package model.algorithms.rounding;

import java.util.LinkedHashMap;

import model.components.networks.sdn.SdnNetwork;
import model.components.networks.virtual.VirtualNetwork;
import model.components.nodes.node.sdn.SdnNode;
import model.components.nodes.node.virtual.VirtualNode;

public class Deterministic extends RoundingAlgorithm
{
	public Deterministic( String name )
	{
		super( name );
	}
	
	@Override
	public LinkedHashMap< VirtualNode, SdnNode > run( VirtualNetwork virtualNetwork, SdnNetwork physicalNetwork, double x[][][], double f[][][] )
	{
		LinkedHashMap< VirtualNode, SdnNode > mappingNodes = new LinkedHashMap< VirtualNode, SdnNode >();
		SdnNetwork netSubCopy = physicalNetwork.getCopy();
		
		for( VirtualNode nodeRequest: virtualNetwork.getVirtualNodes() )
			if( netSubCopy.getNodes().size() != 0 )
			{
				int iNodeReq = nodeRequest.getNumber();
				double sumFlowsMax = -1;
				SdnNode nodeSubSel = null;
				
				for( SdnNode nodeSubstrate: netSubCopy.getSdnNodes() )
					if( nodeRequest.getType().equalsIgnoreCase( nodeSubstrate.getType() ) )
					{
						int iNodeAug =  nodeSubstrate.getNumber() + virtualNetwork.getNodes().size();
						
						double sumFlows = 0;
						
						for( int i = 0; i < virtualNetwork.getVirtualLinks().size(); i++ )
							sumFlows += x[ i ][ iNodeReq ][ iNodeAug ] * ( f[ i ][ iNodeReq ][ iNodeAug ] + f[ i ][ iNodeAug ][ iNodeReq ] );
						
						if( sumFlows > sumFlowsMax )
						{
							sumFlowsMax = sumFlows;
							nodeSubSel = nodeSubstrate;
						}
					}
				
				mappingNodes.put( nodeRequest, nodeSubSel );
				netSubCopy.getNodes().remove( nodeSubSel );
			}
			else
				mappingNodes = null;
		
		return mappingNodes;
	}

}







